// *** LICENSE HEADER ***
// Filename: ./helperfunctions.cpp
// This file is part of Nodewarz 0.1
// Nodewarz is a 3d OpenGL strategy game
// Copyright (C) 2007 CZestmyr
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
// *** END LICENSE HEADER ***
#include "helperfunctions.h"

bool PickAtZPlane(float& xPos, float& yPos, int x, int y) {
    y = _HEIGHT - y;
    GLint viewport[4] = {0, 0, _WIDTH, _HEIGHT};
    GLdouble projection[16];
    GLdouble modelview[16];
    GLdouble farVector[3];
    GLdouble nearVector[3];
    GLdouble directionVector[3];
    GLdouble parameter;

    glGetDoublev(GL_PROJECTION_MATRIX, projection);
    glGetDoublev(GL_MODELVIEW_MATRIX, modelview);

    gluUnProject(x, y, 1, modelview, projection,
                 viewport, farVector, farVector + 1, farVector + 2);
    gluUnProject(x, y, 0, modelview, projection,
                 viewport, nearVector, nearVector + 1, nearVector + 2);

    if (nearVector[2] == farVector[2]) return false;

    for (int i = 0; i < 3; ++i)
        directionVector[i] = farVector[i] - nearVector[i];

    parameter = - nearVector[2] / directionVector[2];
    xPos = nearVector[0] + parameter * directionVector[0];
    yPos = nearVector[1] + parameter * directionVector[1];

    return true;
}

bool Constraintf(float& variable, float minVal, float maxVal) {
    if (variable > maxVal) {
        variable = maxVal;
        return true;
    }
    if (variable < minVal) {
        variable = minVal;
        return true;
    }
    return false;
}

bool Constrainti(int& variable, int minVal, int maxVal) {
    if (variable > maxVal) {
        variable = maxVal;
        return true;
    }
    if (variable < minVal) {
        variable = minVal;
        return true;
    }
    return false;
}

float Distancef(float ax, float ay, float bx, float by) {
    return sqrt((ax -bx)*(ax - bx) + (ay - by)*(ay - by));
}

char* strcpy_safe_my(char* dest, const char* src, unsigned int dstLength){
    unsigned int i;
    for (i = 0; i < dstLength; ++i){
        dest[i] = src[i];
        if (src[i] == 0x00) break;
    }
    if (i == dstLength)
        dest[dstLength-1] = 0x00;
    return dest;
}

Uint32 FormatHost(char a, char b, char c, char d){
    Uint32 ret;
    char* writePointer = (char*)&ret;
    *writePointer = a; ++writePointer;
    *writePointer = b; ++writePointer;
    *writePointer = c; ++writePointer;
    *writePointer = d;
    return ret;
}

Uint16 FormatPort(Uint16 port){
    Uint16 ret;
    SDLNet_Write16(port, &ret);
    return ret;
}
